# -*- coding: utf-8 -*-

# Create your views here.
import operator
from datetime import date

from django.template import RequestContext
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.db.models import Q, ProtectedError

from ..models import Clientes, CuentasClientes
from ..forms import BuscarForm, ClientesForm, CuentaClienteForm, SelectorMesAnio

from .ingresos_y_gastos import actualizar_saldos
from .cotizaciones import pesos_a_dolares_compra


# CLIENTES

def listado_clientes(request):
    """Listado y Busqueda de Clientes"""
    template_name = 'listado_clientes.html'
    if request.user.is_authenticated():
        if request.method == 'POST':
            form = BuscarForm(request.POST)
            if form.is_valid():
                # Posible try a futuro.
                #try:
                text = form.cleaned_data['text']
                text = str(text)
                if text:
                    palabras = text.split()
                    cantidad_palabras = len(palabras)
                    fieldnames = ['nombre', 'apellido', 'telefono1', 'telefono2', 'direccion', 'email1', 'email2']
                    lista_encontrados = []
                    for i in range(0, cantidad_palabras):
                        qgroup = reduce(operator.or_, (Q(**{fieldname + '__icontains': palabras[i]})
                                                       for fieldname in fieldnames))
                        lista_temp = Clientes.objects.filter(qgroup)
                        for cliente in lista_temp:
                            if lista_encontrados.count(cliente) == 0:
                                lista_encontrados.append(cliente)
                else:
                    lista_encontrados = Clientes.objects.all()
                variables = RequestContext(request, {'todo': lista_encontrados, 'form': form})
                return render_to_response(template_name, variables)
                #except:
                return HttpResponseRedirect('/')
            else:
                lista_encontrados = Clientes.objects.all()
                variables = RequestContext(request, {'todo': lista_encontrados, 'form': form})
                return render_to_response(template_name, variables)
        # GET
        else:
            form = BuscarForm()
            lista_clientes = Clientes.objects.all()
            saldos_clientes = {}
            for cliente in lista_clientes:
                cuentas_del_cliente = cliente._get_cuentas()
                if cuentas_del_cliente:
                    try:
                        ultimo_saldo = float(cuentas_del_cliente.order_by('-fecha', '-id')[0].saldoUSD)
                    except:
                        ultimo_saldo = 0
                    saldos_clientes[cliente.id] = round(float(ultimo_saldo), 2)
            variables = RequestContext(request, {'form': form, 'todo': lista_clientes,
                                                 'saldos_clientes': saldos_clientes})
            return render_to_response(template_name, variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def listado_clientes_con_saldo(request):
    if request.user.is_authenticated():
        if request.method == 'POST':
            form = BuscarForm(request.POST)
            if form.is_valid():
                # Posible try a futuro.
                #try:
                text = form.cleaned_data['text']
                text = str(text)
                if text:
                    palabras = text.split()
                    cantidad_palabras = len(palabras)
                    fieldnames = ['nombre', 'apellido', 'telefono1', 'telefono2', 'direccion', 'email1', 'email2']
                    lista_encontrados = []
                    for i in range(0, cantidad_palabras):
                        qgroup = reduce(operator.or_, (Q(**{fieldname + '__icontains': palabras[i]})
                                                       for fieldname in fieldnames))
                        lista_temp = Clientes.objects.filter(qgroup)
                        for cliente in lista_temp:
                            if lista_encontrados.count(cliente) == 0:
                                lista_encontrados.append(cliente)
                else:
                    lista_encontrados = Clientes.objects.all()
                variables = RequestContext(request, {'todo': lista_encontrados, 'form': form})
                return render_to_response('listado_clientes.html', variables)
                #except:
                return HttpResponseRedirect('/')
            else:
                lista_encontrados = Clientes.objects.all()
                variables = RequestContext(request, {'todo': lista_encontrados, 'form': form})
                return render_to_response('listado_clientes.html', variables)
        else:
            form = BuscarForm()
            lista_clientes = Clientes.objects.all()
            lista_con_saldo = []
            saldos_clientes = {}
            for cliente in lista_clientes:
                cuentas_del_cliente = cliente._get_cuentas()
                #cuentas_del_cliente = CuentasClientes.objects.filter('cliente_id'=cliente.id)
                if cuentas_del_cliente:
                    # si la cuenta la ultima fecha es distinta de 0, o sea el ultimo valor de saldo
                    try:
                        ultimo_saldo = float(cuentas_del_cliente.order_by('-fecha', '-id')[0].saldoUSD)
                    except:
                        ultimo_saldo = 0
                    if round(float(ultimo_saldo), 1) != 0:
                        # se agrega al diccionario de clientes con saldo
                        saldos_clientes[cliente.id] = round(float(ultimo_saldo), 2)
                        lista_con_saldo.append(cliente)
            variables = RequestContext(request, {'form': form, 'todo': lista_con_saldo, 'con_saldo': True,
                                                 'saldos_clientes': saldos_clientes})
            return render_to_response('listado_clientes.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def agregar_clientes(request):
    """Agrega Clientes"""
    if request.user.is_authenticated():
        if request.method == 'POST':
            form = ClientesForm(request.POST)
            if form.is_valid():
                registro = form.save()
                try:
                    registro.cumple = date(1900, int(form.cleaned_data['mesCumple']),
                                           int(form.cleaned_data['diaCumple']))
                except ValueError:
                    registro.cumple = None
                registro.save()
                return HttpResponseRedirect('/clientes/listado/')
        else:
            form = ClientesForm()
        variables = RequestContext(request, {'form': form})
        return render_to_response('agregar_clientes.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def editar_clientes(request, clienteid):
    """Edita Clientes"""
    if request.user.is_authenticated():
        r = Clientes.objects.get(pk=clienteid)
        if request.method == 'POST':
            form = ClientesForm(request.POST, instance=r)
            if form.is_valid():
                registro = form.save()
                try:
                    registro.cumple = date(1900, int(form.cleaned_data['mesCumple']),
                                           int(form.cleaned_data['diaCumple']))
                except ValueError:
                    registro.cumple = None
                registro.save()
                return HttpResponseRedirect('/clientes/listado/')
        else:
            form = ClientesForm(instance=r)
        variables = RequestContext(request, {
            'form': form,
            'r': r,
        })
        return render_to_response('editar_clientes.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def check_clientes(request, clienteid):
    """Confirmar antes de eliminar"""
    if request.user.is_authenticated():
        cliente = Clientes.objects.get(pk=clienteid)
        variables = RequestContext(request, {'cliente': cliente})
        return render_to_response('borrado_clientes.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def borrar_clientes(request, clienteid):
    """Elimina Clientes"""
    if request.user.is_authenticated():
        r = Clientes.objects.get(pk=clienteid)
        try:
            r.delete()
        except ProtectedError:
            variables = RequestContext(request, {'mensaje': 'NO se puede eliminar porque tiene cuentas asociadas'})
            return render_to_response('error.html', variables)
        return HttpResponseRedirect('/clientes/listado/')
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def ver_clientes(request, clienteid):
    """Muestra datos del Cliente seleccionado"""
    if request.user.is_authenticated():
        cliente = Clientes.objects.get(pk=clienteid)
        variables = RequestContext(request, {'cliente': cliente})
        return render_to_response('ver_clientes.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)

# CUENTA DEL CLIENTE

def listado_cuenta_cliente(request, clienteid, formid):
    """Listado de Cuenta de cliente"""
    template_name = 'listado_cuentaCliente.html'

    if request.user.is_authenticated():

        cliente = Clientes.objects.get(pk=clienteid)

        if request.method == 'POST':
            # si se ingresa un gasto en el primer form
            if formid == '1':
                form = CuentaClienteForm(request.POST)
                if form.is_valid():
                    registro = form.save()
                    registro.cliente = cliente
                    registro.save()
                    if registro.moneda == 'UYU':
                        if registro.debe and registro.haber > 0:
                            debe = round(pesos_a_dolares_compra(registro.debe, registro.fecha), 2) * (-1)
                            haber = round(pesos_a_dolares_compra(registro.haber, registro.fecha), 2)
                            registro.subtotal = debe + haber
                            registro.saldoUSD = debe + haber
                            registro.save()
                        if registro.debe > 0:
                            registro.subtotal = pesos_a_dolares_compra(registro.debe, registro.fecha) * (-1)
                            registro.save()
                            registro.saldoUSD = pesos_a_dolares_compra(registro.debe, registro.fecha) * (-1)
                        if registro.haber > 0:
                            registro.subtotal = pesos_a_dolares_compra(registro.haber, registro.fecha)
                            registro.saldoUSD = pesos_a_dolares_compra(registro.haber, registro.fecha)
                            registro.save()
                    if registro.moneda == 'USD':
                        if registro.debe and registro.haber > 0:
                            debe = round(registro.debe, 2) * (-1)
                            haber = round(registro.haber, 2)
                            registro.subtotal = debe + haber
                            registro.saldoUSD = debe + haber
                            registro.save()
                        if registro.debe > 0:
                            registro.subtotal = registro.debe * (-1)
                            registro.saldoUSD = registro.debe * (-1)
                            registro.save()
                        if registro.haber > 0:
                            registro.subtotal = registro.haber
                            registro.saldoUSD = registro.haber
                            registro.save()
                    return HttpResponseRedirect('/clientes/cuenta/listado/%s/0/' % clienteid)
            # si se selecciona un mes y un año en el segundo form
            if formid == '2':
                form = CuentaClienteForm()
                form2 = SelectorMesAnio(request.POST)
                if form2.is_valid():
                    mes = form2.cleaned_data['mes']
                    anio = form2.cleaned_data['anio']
                    saldo_anterior = calculo_saldo_mes_anterior_cli(mes, anio, clienteid)
                    cuentas_cliente = CuentasClientes.objects.filter(fecha__month=mes, fecha__year=anio,
                                                                     cliente=cliente).order_by('fecha', 'id')
                    variables = RequestContext(request, {
                        'form': form,
                        'form2': form2,
                        'mes': mes,
                        'anio': anio,
                        'todo': cuentas_cliente,
                        'cliente': cliente,
                        'saldo_anterior': saldo_anterior,
                    })
                    return render_to_response(template_name, variables)
                else:
                    return HttpResponseRedirect('/clientes/cuenta/listado/%s/0/' % clienteid)

        # Form GET
        else:
            form = CuentaClienteForm()
            form2 = SelectorMesAnio()
            # Si clickea en Ver Todos
            if formid == '3':
                cuentas_cliente = CuentasClientes.objects.filter(cliente=cliente).order_by('fecha', 'id')
                mes = 0
                variables = RequestContext(request, {
                    'form': form,
                    'form2': form2,
                    'mes': mes,
                    'todo': cuentas_cliente,
                    'cliente': cliente,
                    'saldo_anterior': 0,
                })
                cuentas_cliente = CuentasClientes.objects.filter(cliente=cliente).order_by('fecha', 'id')
                actualizar_saldos(cuentas_cliente)
                return render_to_response(template_name, variables)
            else:
                mes = str(date.today().month)
                anio = str(date.today().year)
                saldo_anterior = calculo_saldo_mes_anterior_cli(mes, anio, clienteid)
                cuentas_cliente = CuentasClientes.objects.filter(
                    fecha__month=mes, fecha__year=anio, cliente=cliente).order_by('fecha', 'id')
                variables = RequestContext(request, {
                    'form': form,
                    'form2': form2,
                    'mes': mes,
                    'anio': anio,
                    'todo': cuentas_cliente,
                    'cliente': cliente,
                    'saldo_anterior': saldo_anterior,
                })
                cuentas_cliente = CuentasClientes.objects.filter(cliente=cliente).order_by('fecha', 'id')
                actualizar_saldos(cuentas_cliente)
                return render_to_response(template_name, variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def editar_cuenta_cliente(request, registroid):
    """Edita Cuenta de cliente"""
    if request.user.is_authenticated():
        r = CuentasClientes.objects.get(pk=registroid)
        cliente = Clientes.objects.filter(id=r.cliente_id)
        if request.method == 'POST':
            form = CuentaClienteForm(request.POST, instance=r)
            if form.is_valid():
                registro = form.save()
                if registro.moneda == 'UYU':
                    if registro.debe > 0:
                        registro.subtotal = pesos_a_dolares_compra(registro.debe, registro.fecha) * (-1)
                        registro.save()
                    if registro.haber > 0:
                        registro.subtotal = pesos_a_dolares_compra(registro.haber, registro.fecha)
                        registro.save()
                if registro.moneda == 'USD':
                    if registro.debe > 0:
                        registro.subtotal = registro.debe * (-1)
                        registro.save()
                    if registro.haber > 0:
                        registro.subtotal = registro.haber
                        registro.save()
                cuentas_cliente = CuentasClientes.objects.filter(cliente=cliente).order_by('fecha', 'id')
                actualizar_saldos(cuentas_cliente)
                return HttpResponseRedirect('/clientes/cuenta/listado/%s/0/' % registro.cliente.id)
        else:
            form = CuentaClienteForm(instance=r)
        variables = RequestContext(request, {
            'form': form,
            'cliente': r.cliente,
        })
        return render_to_response('editar_cuentaCliente.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def check_cuenta_cliente(request, registroid):
    """Confirmar antes de eliminar"""
    if request.user.is_authenticated():
        registro = CuentasClientes.objects.get(pk=registroid)
        variables = RequestContext(request, {'registro': registro})
        return render_to_response('borrado_cuentaCliente.html', variables)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def borrar_cuenta_cliente(request, registroid):
    """Elimina registro de cuenta"""
    if request.user.is_authenticated():
        r = CuentasClientes.objects.get(pk=registroid)
        r.delete()
        return HttpResponseRedirect('/clientes/cuenta/listado/%s/0/' % r.cliente.id)
    else:
        return HttpResponseRedirect('/login/?next=%s' % request.path)


def actualizar_saldos_clientes(request):
    clientes = Clientes.objects.all()
    for cli in clientes:
        todos = CuentasClientes.objects.filter(cliente=cli.id).filter(fecha__range=(date(2014, 2, 20), date.today()))
        cli.saldoUSD = actualizar_saldos(todos)
        cli.saldo_actualizado = True
        cli.save()
    return HttpResponseRedirect('/clientes/con-saldo/')

def calculo_saldo_mes_anterior_cli(mes, anio, clienteid):
    """Calcula el saldo del mes anterior"""
    cuentas_mes_anterior = []
    saldo_mes_anterior = None
    mes_anterior = mes
    anio_anterior = anio
    cliente = Clientes.objects.get(pk=clienteid)
    while len(cuentas_mes_anterior) == 0:
        if mes_anterior == '1':
            mes_anterior = '12'
            anio_anterior = str(int(anio_anterior) - 1)
        else:
            mes_anterior = str(int(mes_anterior) - 1)

        if anio_anterior == '2000':
            saldo_mes_anterior = 0
            break
        else:
            cuentas_mes_anterior = CuentasClientes.objects.filter(cliente=cliente, fecha__month=mes_anterior,
                                                                  fecha__year=anio_anterior).order_by('-fecha', '-id')
    if saldo_mes_anterior != 0:
        if len(cuentas_mes_anterior) > 0:
            if cuentas_mes_anterior[0].saldoUSD:
                saldo_mes_anterior = round(cuentas_mes_anterior[0].saldoUSD, 2)
            else:
                cuentas_cliente = CuentasClientes.objects.filter(cliente=cliente).order_by('fecha', 'id')
                actualizar_saldos(cuentas_cliente)
                cuentas_mes_anterior = CuentasClientes.objects.filter(cliente=cliente, fecha__month=mes_anterior,
                                                                  fecha__year=anio_anterior).order_by('-fecha', '-id')
                saldo_mes_anterior = round(cuentas_mes_anterior[0].saldoUSD, 2)
        else:
            saldo_mes_anterior = 0
    return saldo_mes_anterior